<template>
    <view class="toast" :class="[theme]" :style="wrapperStyle">
        <view class="item" :class="[{ visible: item.active }, item.type]" v-for="item in queue" :key="item.id"
            @transitionend="onTransitionEnd(item.id)">
            <image class="icon" :src="`/static/toast/${item.type}_${theme}.png`" mode="aspectFill" />
            <view class="message">
                {{ item.message }}
            </view>
        </view>
    </view>
</template>

<script setup>
import { computed, inject, onMounted, onUnmounted, reactive } from 'vue'

const theme = inject('theme')

const wrapperStyle = computed(() => {
    return {
        paddingTop: `${uni.getSystemInfoSync().statusBarHeight}px`
    }
})

const MAX_COUNT = 5

const DEFAULT_OPTIONS = {
    id: 0,
    type: 'success',
    message: '',
    duration: 2000,
    active: false,
    timer: 0
}

const queue = reactive([])

const show = (options = {}) => {
    const item = {
        ...DEFAULT_OPTIONS,
        ...options
    }

    const id = Date.now()
    item.id = id

    if (queue.length > MAX_COUNT) {
        const removed = queue.shift()
        clearTimeout(removed.timer)
    }

    queue.push(item)

    setTimeout(showQueue, 50)
}

const showQueue = () => {
    const item = queue.at(-1)
    item.active = true

    item.timer = setTimeout(() => {
        item.active = false
    }, item.duration)
}

const onTransitionEnd = (id) => {
    const index = queue.findIndex(item => item.id === id)
    if (index !== -1 && !queue.at(index).active) queue.splice(index, 1)
}

onMounted(() => {
    uni.$on('toast', show)
})

onUnmounted(() => {
    uni.$off('toast', show)
})
</script>

<style lang="scss" scoped>
.toast {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    width: 100vw;
    z-index: 9;
    pointer-events: none;

    .item {
        display: flex;
        align-items: center;
        justify-content: center;
        flex: 0 0 auto;
        width: max-content;
        margin-bottom: 7.63rpx;
        padding: 11.45rpx 22.9rpx 11.45rpx 11.45rpx;
        background-color: #00CDE3;
        color: #FFFFFF;
        font-size: 26.72rpx;
        line-height: 38.17rpx;
        border-radius: 30.53rpx;
        transform: translateY(-19.08rpx);
        opacity: 0;
        transition: all 0.2s ease;

        &.visible {
            transform: translateY(0);
            opacity: 1;
        }

        &.fail {
            background-color: #FF2C6C;
        }
    }

    .icon {
        flex-shrink: 0;
        width: 38.17rpx;
        height: 38.17rpx;
        margin-right: 15.27rpx;
    }

    &.dark {
        .item {
            background-color: #008492;
            color: #101318;

            &.fail {
                background-color: #C82355;
            }
        }
    }
}
</style>